home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
multiuser
/
src
/
library
/
segment.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-29
|
8KB
|
304 lines
/************************************************************
* MultiUser - MultiUser Task/File Support System *
* --------------------------------------------------------- *
* Segment Management *
* --------------------------------------------------------- *
* © Copyright 1993-1994 Geert Uytterhoeven *
* All Rights Reserved. *
************************************************************/
#include <exec/execbase.h>
#include <exec/alerts.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include "Memory.h"
#include "Segment.h"
#include "Misc.h"
#include "Config.h"
#include "Locale.h"
#include "LibHeader.h"
#include "Task.h"
/*
* Static Routines
*/
static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner);
static void RemSegNode(struct muSegNode *snode);
static struct muSegNode *FindSegNode(BPTR SegList);
static struct muExtOwner *GetSegOwner(BPTR seglist);
/*
* Allocate and Add a Segment Node
*
* Make sure you have access to the list (via ObtainSemaphore(Shared))!!
*/
static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner)
{
struct muSegNode *snode;
if (snode = MAlloc(sizeof(struct muSegNode))) {
snode->SegList = seglist;
snode->Owner.uid = (owner & muMASK_UID)>>16;
snode->Owner.gid = owner & muMASK_GID;
AddHead((struct List *)&muBase->SegOwnerList, (struct Node *)&snode->Node);
}
return(snode);
}
/*
* Remove and Deallocate a Segment Node
*
* Make sure you have access to the list (via ObtainSemaphore(Shared))!!
*/
static void __inline RemSegNode(struct muSegNode *snode)
{
Remove((struct Node *)&snode->Node);
Free(snode, sizeof(struct muSegNode));
}
/*
* Find the Segment Node for a given SegList
*
* Make sure you have access to the list (via ObtainSemaphore(Shared))!!
*/
static struct muSegNode *FindSegNode(BPTR seglist)
{
struct MinNode *node;
struct muSegNode *snode;
for (node = muBase->SegOwnerList.mlh_Head;
node->mln_Succ && ((snode = (struct muSegNode *)node)->SegList != seglist);
node = node->mln_Succ);
if (!node->mln_Succ)
snode = NULL;
return(snode);
}
/*
* Get the owner of a Segment
*
* Make sure you have access to the list (via ObtainSemaphore(Shared))!!
*/
static struct muExtOwner *GetSegOwner(BPTR seglist)
{
struct muExtOwner *owner = NULL;
struct muSegNode *snode;
ObtainSemaphoreShared(&muBase->SegOwnerSem);
if (snode = FindSegNode(seglist))
owner = &snode->Owner;
ReleaseSemaphore(&muBase->SegOwnerSem);
return(owner);
}
/*
* Init Segment List
*/
void InitSegList(void)
{
ObtainSemaphore(&muBase->SegOwnerSem);
NewList((struct List *)&muBase->SegOwnerList);
ReleaseSemaphore(&muBase->SegOwnerSem);
}
/*
* Replacement for the dos.library LoadSeg() function
*/
BPTR __asm __saveds NEWLoadSeg(register __d1 STRPTR name, register __a6 struct DosLibrary *dosbase)
{
BPTR fl;
struct FileInfoBlock *fib;
ULONG owner = muOWNER_NOBODY;
BPTR seglist;
if (name && (fl = Lock(name, ACCESS_READ))) {
if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
(fib = AllocDosObject(DOS_FIB, NULL))) {
if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
FreeDosObject(DOS_FIB, fib);
}
UnLock(fl);
}
seglist = muBase->OLDLoadSeg(name, dosbase);
if (owner & muMASK_UID) {
ObtainSemaphore(&muBase->SegOwnerSem);
AddSegNode(seglist, owner);
ReleaseSemaphore(&muBase->SegOwnerSem);
}
return(seglist);
}
/*
* Replacement for the dos.library NewLoadSeg() function
*/
BPTR __asm __saveds NEWNewLoadSeg(register __d1 STRPTR name, register __d2 struct TagItem *tags,
register __a6 struct DosLibrary *dosbase)
{
BPTR fl;
struct FileInfoBlock *fib;
ULONG owner = muOWNER_NOBODY;
BPTR seglist;
if (name && (fl = Lock(name, ACCESS_READ))) {
if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
(fib = AllocDosObject(DOS_FIB, NULL))) {
if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
FreeDosObject(DOS_FIB, fib);
}
UnLock(fl);
}
seglist = muBase->OLDNewLoadSeg(name, tags, dosbase);
if (owner & muMASK_UID) {
ObtainSemaphore(&muBase->SegOwnerSem);
AddSegNode(seglist, owner);
ReleaseSemaphore(&muBase->SegOwnerSem);
}
return(seglist);
}
/*
* Replacement for the dos.library UnLoadSeg() function
*/
BOOL __asm __saveds NEWUnLoadSeg(register __d1 BPTR seglist, register __a6 struct DosLibrary *dosbase)
{
struct muSegNode *snode;
ObtainSemaphoreShared(&muBase->SegOwnerSem);
if (snode = FindSegNode(seglist))
RemSegNode(snode);
ReleaseSemaphore(&muBase->SegOwnerSem);
return(muBase->OLDUnLoadSeg(seglist, dosbase));
}
/*
* Replacement for the dos.library InternalLoadSeg() function
*/
BPTR __asm __saveds NEWInternalLoadSeg(register __d0 BPTR fh, register __a0 BPTR table,
register __a1 LONG *functionarray, register __a2 LONG *stack,
register __a6 struct DosLibrary *dosbase)
{
struct FileInfoBlock *fib;
ULONG owner = muOWNER_NOBODY;
BPTR seglist;
if (fh && CheckmuFSVolume(((struct FileHandle *)BADDR(fh))->fh_Type) &&
(fib = AllocDosObject(DOS_FIB, NULL))) {
if (ExamineFH(fh, fib) && (fib->fib_Protection & muFIBF_SET_UID))
owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
FreeDosObject(DOS_FIB, fib);
}
seglist = muBase->OLDInternalLoadSeg(fh, table, functionarray, stack, dosbase);
if (owner & muMASK_UID) {
ObtainSemaphore(&muBase->SegOwnerSem);
AddSegNode(seglist, owner);
ReleaseSemaphore(&muBase->SegOwnerSem);
}
return(seglist);
}
/*
* Replacement for the dos.library InternalUnLoadSeg() function
*/
BOOL __asm __saveds NEWInternalUnLoadSeg(register __d1 BPTR seglist, register __a1 void (*freefunc)(),
register __a6 struct DosLibrary *dosbase)
{
struct muSegNode *snode;
ObtainSemaphoreShared(&muBase->SegOwnerSem);
if (snode = FindSegNode(seglist))
RemSegNode(snode);
ReleaseSemaphore(&muBase->SegOwnerSem);
return(muBase->OLDInternalUnLoadSeg(seglist, freefunc, dosbase));
}
/*
* Replacement for the dos.library CreateProc() function
*/
struct Process __asm __saveds *NEWCreateProc(register __d1 STRPTR name, register __d2 LONG pri,
register __d3 BPTR seglist, register __d4 LONG stacksize,
register __a6 struct DosLibrary *dosbase)
{
struct muExtOwner *owner;
struct Process *proc;
if (owner = GetSegOwner(seglist))
PushTask(SysBase->ThisTask, owner);
proc = muBase->OLDCreateProc(name, pri, seglist, stacksize, dosbase);
if (owner)
PopTask(SysBase->ThisTask);
return(proc);
}
/*
* Replacement for the dos.library CreateNewProc() function
*/
struct Process __asm __saveds *NEWCreateNewProc(register __d1 struct TagItem *tags,
register __a6 struct DosLibrary *dosbase)
{
struct muExtOwner *owner = NULL;
struct Process *proc;
BPTR seglist;
if (tags && (seglist = (BPTR)GetTagData(NP_Seglist, NULL, tags)) && (owner = GetSegOwner(seglist)))
PushTask(SysBase->ThisTask, owner);
proc = muBase->OLDCreateNewProc(tags, dosbase);
if (owner)
PopTask(SysBase->ThisTask);
return(proc);
}
/*
* Replacement for the dos.library RunCommand() function
*/
LONG __asm __saveds NEWRunCommand(register __d1 BPTR seglist, register __d2 ULONG stacksize,
register __d3 STRPTR argptr, register __d4 ULONG argsize,
register __a6 struct DosLibrary *dosbase)
{
struct muExtOwner *owner;
LONG rc;
if (owner = GetSegOwner(seglist))
PushTask(SysBase->ThisTask, owner);
rc = muBase->OLDRunCommand(seglist, stacksize, argptr, argsize, dosbase);
if (owner)
PopTask(SysBase->ThisTask);
return(rc);
}